package client.ui.states;

/*
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * GameState.java
 *
 * Steven Louie Apr. 8, 2012
 */
import client.ActinoClient;
import client.controllers.Animator;
import client.models.ActinoPlayer;
import client.models.ClientMap;
import client.models.Direction;
import client.net.ChatMessage;
import client.tools.ImagesLoader;
import client.ui.StateManager;
import client.ui.controllers.GameScreen;
import client.ui.controllers.WindowScreen;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.builder.LayerBuilder;
import de.lessvoid.nifty.builder.PanelBuilder;
import de.lessvoid.nifty.builder.ScreenBuilder;
import de.lessvoid.nifty.builder.TextBuilder;
import de.lessvoid.nifty.controls.ListBox;
import de.lessvoid.nifty.controls.button.builder.ButtonBuilder;
import de.lessvoid.nifty.controls.listbox.builder.ListBoxBuilder;
import de.lessvoid.nifty.controls.textfield.builder.TextFieldBuilder;
import de.lessvoid.nifty.loaderv2.NiftyLoader;
import de.lessvoid.nifty.loaderv2.types.NiftyType;
import de.lessvoid.nifty.screen.Screen;
import de.lessvoid.nifty.slick2d.NiftyOverlayBasicGameState;
import de.lessvoid.nifty.slick2d.input.PlainSlickInputSystem;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.newdawn.slick.*;
import org.newdawn.slick.state.StateBasedGame;

public class GameState extends NiftyOverlayBasicGameState {

    private ActinoClient client;
    private Nifty nifty;
    private ClientMap map;
    private String mapName;
    private ActinoPlayer player;
    private Animator anim;

    @Override
    protected void prepareNifty(Nifty nifty, StateBasedGame sbg) {
        this.client = (ActinoClient) sbg;
        this.nifty = nifty;

        NiftyType niftyType = new NiftyType();
        try {
            NiftyLoader niftyLoader = nifty.getLoader();
            niftyLoader.loadStyleFile("nifty-styles.nxs", "nifty-default-styles.xml", niftyType, nifty);
            niftyLoader.loadControlFile("nifty-controls.nxs", "nifty-default-controls.xml", niftyType);
            niftyType.create(nifty, nifty.getTimeProvider());
        } catch (Exception e) {
            Logger.getLogger(GameState.class.getName()).log(Level.SEVERE, null, e);
        }

        Screen gameScreen = new ScreenBuilder("start") {

            {
                controller(new GameScreen());
                layer(new LayerBuilder() {

                    {
                        childLayoutAbsolute();
                        backgroundColor("#00000000");
                        panel(new PanelBuilder("hud") {

                            {
                                style("nifty-panel-no-shadow");
                                childLayoutAbsolute();
                                x("0%");
                                y("93%");
                                width("100%");
                                height("7%");
                                backgroundColor("#00000000");
                            }
                        });
                        panel(new PanelBuilder("chatpanel") {

                            {
                                childLayoutAbsolute();
                                alignLeft();
                                x("0%");
                                y("71.5%");
                                width("60%");
                                height("21%");
                                backgroundColor("#00000000");
                                panel(new PanelBuilder("chatarea") {

                                    {
                                        childLayoutHorizontal();
                                        alignLeft();
                                        width("100%");
                                        height("120px");
                                        x("0%");
                                        y("0%");
                                        control(new ListBoxBuilder("chatbox") {

                                            {
                                                backgroundColor("#000000e0");
                                                color("#0000000e0");
                                                hideHorizontalScrollbar();
                                                showVerticalScrollbar();
                                                displayItems(7);
                                                selectionModeDisabled();
                                                text(new TextBuilder("chattext") {

                                                    {
                                                        font("res/fonts/REFSAN.ttf");
                                                        alignLeft();
                                                        textHAlignLeft();
                                                        width("100%");
                                                        height("11px");
                                                        wrap(true);
                                                    }
                                                });
                                            }
                                        });
                                    }
                                });
                                panel(new PanelBuilder("chatline") {

                                    {
                                        childLayoutHorizontal();
                                        alignLeft();
                                        width("100%");
                                        height("18px");
                                        x("0%");
                                        y("90%");
                                        control(new TextFieldBuilder("chatinput") {

                                            {
                                                width("85%");
                                                height("100%");
                                            }
                                        });
                                        control(new ButtonBuilder("chatbutton", "Send") {

                                            {
                                                width("15%");
                                                height("100%");
                                                interactOnClick("sendMessage()");
                                            }
                                        });
                                    }
                                });
                            }
                        });
                    }
                });
            }
        }.build(nifty);

        nifty.addScreen(gameScreen.getScreenId(), gameScreen);
    }

    @Override
    public int getID() {
        return StateManager.GAME;
    }

    @Override
    protected void enterState(GameContainer gc, StateBasedGame sbg) throws SlickException {
        getNifty().gotoScreen("start");
        this.player = client.getPlayer();
    }

    @Override
    protected void initGameAndGUI(GameContainer gc, StateBasedGame sbg) throws SlickException {
        initNifty(gc, sbg, new PlainSlickInputSystem());
        anim = new Animator();
        map = new ClientMap("/res/maps/-4.2.tmx", "/res/maps/");
        mapName = map.getMapProperty("name", "Unknown map name");
        ImagesLoader.getInstance();
    }

    @Override
    protected void leaveState(GameContainer gc, StateBasedGame sbg) throws SlickException {
    }

    @Override
    protected void renderGame(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
        g.clear();
        g.setColor(Color.black);
        g.fillRect(0, 0, 800, 600);
        map.renderMapWithoutWalkBehind(g, player.px, player.py);
        renderPlayers(g);
        map.renderWalkBehindMap(g, player.px, player.py);
    }

    private void renderPlayers(Graphics g) {
        g.setColor(Color.white);
        g.drawImage(player.currentImage, 400, 300);
        String loc = "(" + player.x + "," + player.y + ")";
        g.drawString(player.name, 380, 270);
        g.drawString(loc, 380, 285);

        ArrayList<ActinoPlayer> otherPlayers = client.getOtherPlayers();
        for (int j = 0; j < otherPlayers.size(); ++j) {
            int xOff = otherPlayers.get(j).px - player.px;
            int yOff = otherPlayers.get(j).py - player.py;
            g.drawImage(otherPlayers.get(j).currentImage, 400 + xOff, 300 + yOff);
            loc = "(" + otherPlayers.get(j).x + "," + otherPlayers.get(j).y + ")";
            g.drawString(otherPlayers.get(j).name, 380 + xOff, 270 + yOff);
            g.drawString(loc, 380 + xOff, 285 + yOff);
        }
    }

    @Override
    protected void updateGame(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
        if (player.animating) {
            anim.animatePlayer(player, map, player.speed, delta);
            client.getTcp().sendMovement(player);
        }
    }

    public void displayMessage(ChatMessage message) {
        String s = message.source + ": " + message.text;
        ListBox box = nifty.getCurrentScreen().findNiftyControl("chatbox", ListBox.class);
        box.addItem(s);
        box.setFocusItem(s);
        box.refresh();
        if (box.itemCount() > 40) {
            box.removeItemByIndex(0);
        }
    }

    public void createNextWindow(final String text) {
        Screen nextWindow = new ScreenBuilder("start") {

            {
                controller(new WindowScreen());
                layer(new LayerBuilder() {

                    {
                        childLayoutCenter();
                        backgroundColor("#000000E0");
                        panel(new PanelBuilder("nextwindow") {

                            {
                                childLayoutAbsolute();
                                text(new TextBuilder("chattext") {

                                    {
                                        text(text);
                                        font("res/fonts/REFSAN.ttf");
                                        width("80%");
                                        height("*");
                                        x("10%");
                                        y("10%");
                                        wrap(true);
                                    }
                                });
                            }
                        });
                    }
                });
            }
        }.build(nifty);
        nifty.addScreen(nextWindow.getScreenId(), nextWindow);
    }

    @Override
    public void keyPressed(int key, char c) {
        if (key == Input.KEY_DOWN) {
            if (!player.animating) {
                if (player.dir != Direction.DOWN || !map.isColliding(player)) {
                    player.moveDown();
                    client.getTcp().sendMovement(player);
                }
            }
        } else if (key == Input.KEY_UP) {
            if (!player.animating) {
                if (player.dir != Direction.UP || !map.isColliding(player)) {
                    player.moveUp();
                    client.getTcp().sendMovement(player);
                }
            }
        } else if (key == Input.KEY_RIGHT) {
            if (!player.animating) {
                if (player.dir != Direction.RIGHT || !map.isColliding(player)) {
                    player.moveRight();
                    client.getTcp().sendMovement(player);
                }
            }
        } else if (key == Input.KEY_LEFT) {
            if (!player.animating) {
                if (player.dir != Direction.LEFT || !map.isColliding(player)) {
                    player.moveLeft();
                    client.getTcp().sendMovement(player);
                }
            }
        } else if (key == Input.KEY_EQUALS) {
            if (player.speed < 8 && !player.animating) {
                player.speed *= 2;
            }
        } else if (key == Input.KEY_MINUS) {
            if (player.speed > 1 && !player.animating) {
                player.speed /= 2;
            }
        } else if (key == Input.KEY_B) {
            map.interact(player);
        }
    }
}
